// View Class
// Takes information from game objects, and renders them to the screen however it sees fit
#pragma once

#include "..\Shared\ObjectTypes.h"
#include "MeshManager.h"
#include "..\Shared\Coordinate.h"
#include "..\Shared\LRSInformation.h"
#include "Sky.h"
#include "FloatingTextManager.h"

class Sky; // forward declaration in order to compile. View needs Sky and Sky needs View...

#define VIEW View::Instance()

const int WORLD_X_SCALE = 20;
const int WORLD_Y_SCALE = 20;

#define NUMSTARS_Y				13
#define NUMSTARS_XSCALE			0.25f
#define NUMSTARS_YSCALE			0.2f
#define TEXTCOLOR_NUMSTARS		D3DCOLOR_XRGB(255, 255, 0)

#define TEXTSCALE_LRS			1

#define NUMENEMIES_Y			13
#define NUMENEMIES_XSCALE		-0.2f
#define NUMENEMIES_YSCALE		0.2f
#define TEXTCOLOR_NUMENEMIES	D3DCOLOR_XRGB(255, 0, 0)


D3DXVECTOR3 ConvertCoordinateToD3DXVector3(Coordinate c, int yPosition = 0, float xScaleMod = 0.0f, float yScaleMod = 0.0f);
D3DXVECTOR3 ConvertCoordinateToD3DXVector3(int x, int y, int yPosition = 0, float xScaleMod = 0.0f, float yScaleMod = 0.0f);

const float OBJECT_SCALE = 1.5f;

class View
{
private:
	View();
	View(const View& v);
	View* operator=(const View& v);
	~View();
	
	// VP matrices
	D3DXMATRIX mProj;
	D3DXMATRIX mView;
	D3DXVECTOR3 mCameraPos;

	// effect info
	ID3DXEffect* mFX;
	D3DXHANDLE   mhTech;
	D3DXHANDLE   mhWorld;
	D3DXHANDLE   mhWorldInvTrans;
	D3DXHANDLE   mhWVP;
	D3DXHANDLE   mhAmbientMtrl;
	D3DXHANDLE   mhAmbientLight;
	D3DXHANDLE   mhDiffuseMtrl;
	D3DXHANDLE   mhDiffuseLight;
	D3DXHANDLE   mhSpecMtrl;
	D3DXHANDLE   mhSpecLight;
	D3DXHANDLE   mhSpecPower;
	D3DXHANDLE   mhLightVecW;
	D3DXHANDLE   mhEyePos;
	D3DXHANDLE   mhTex;

	// lighting info
	D3DXCOLOR	mAmbientLight;
	D3DXCOLOR	mDiffuseLight;
	D3DXCOLOR	mSpecLight;
	D3DXVECTOR3	mLightVecW;
	D3DXVECTOR3	mAttenuation012;

	// skybox
	Sky* mSky;
	
public:
	// Initializes the FX file
	void InitializeFX(void);

	// Initializes the Projection matrix
	// Should be called each time the screen size changes
	void InitializeProjectionMatrix(int w, int h);

	// initializes lighting
	void InitializeLighting(void);

	void RenderObject(ObjectType type, D3DXMATRIX transform); // renders the object to the screen based on the given D3DXMATRIX transform
	void RenderObject(ObjectType type, Coordinate c);	// renders the object to the screen based on it's coordinate location
	void RenderObject(ObjectType type, int x, int y);	// renders the object to the screen based on it's x/y position
	void RenderLRSInfo(LRSInformation info, int x, int y, ID3DXFont* font);	// renders a UI element with the LRS information on it

	// renders the skybox
	void RenderSkyBox();

	// updates the new view and proj matricies
	void UpdateView(D3DXVECTOR3 pos, D3DXVECTOR3 target, D3DXVECTOR3 up);

	// releases all memory assets
	void ClearAll(void);

	// performs necessary functions when a device is lost
	void OnLostDevice(void);

	// performs necessary functions when a device is reset
	void OnResetDevice(void);

	// begins the D3D Scene
	void BeginScene(void);

	// ends the D3D scene
	void EndScene(void);

	//////////////////
	// Mutators/Accessors
	//////////////////
	// gets the projection matrix
	D3DXMATRIX GetProjectionMatrix(void);

	// gets the view matrix
	D3DXMATRIX GetViewMatrix(void);

	// gets the camera position
	D3DXVECTOR3 GetCameraPos(void);

	// the view instance
	static View* Instance();

	

};